/**
* @file   DxFuncs.cpp
* @brief  Implementation file for class DxFuncs
* @date   2011-04-08 09:22:00
* @author Yanze Lian
* @email  <yanzel@gmail.com>
*/

#include "stdafx.h"
#include "DxFuncs.h"


DxFuncs::DxFuncs()
{
}

DxFuncs::~DxFuncs()
{
}

HRESULT DxFuncs::AddFilterByCLSID(
						 IGraphBuilder *pGraph,  // Pointer to the Filter Graph Manager.
						 const GUID& clsid,      // CLSID of the filter to create.
						 LPCWSTR wszName,        // A name for the filter.
						 IBaseFilter **ppF)      // Receives a pointer to the filter.
{
	if (!pGraph || ! ppF) return E_POINTER;
	*ppF = 0;
	IBaseFilter *pF = 0;
	HRESULT hr = CoCreateInstance(clsid, 0, CLSCTX_INPROC_SERVER,
		IID_IBaseFilter, reinterpret_cast<void**>(&pF));
	if (SUCCEEDED(hr))
	{
		hr = pGraph->AddFilter(pF, wszName);
		if (SUCCEEDED(hr))
			*ppF = pF;
		else
			pF->Release();
	}
	return hr;
}

HRESULT DxFuncs::GetUnconnectedPin(
						  IBaseFilter *pFilter,   // Pointer to the filter.
						  PIN_DIRECTION PinDir,   // Direction of the pin to find.
						  IPin **ppPin)           // Receives a pointer to the pin.
{
	*ppPin = 0;
	IEnumPins *pEnum = 0;
	IPin *pPin = 0;
	HRESULT hr = pFilter->EnumPins(&pEnum);
	if (FAILED(hr))
	{
		return hr;
	}
	while (pEnum->Next(1, &pPin, NULL) == S_OK)
	{
		PIN_DIRECTION ThisPinDir;
		pPin->QueryDirection(&ThisPinDir);
		if (ThisPinDir == PinDir)
		{
			IPin *pTmp = 0;
			hr = pPin->ConnectedTo(&pTmp);
			if (SUCCEEDED(hr))  // Already connected, not the pin we want.
			{
				pTmp->Release();
			}
			else  // Unconnected, this is the pin we want.
			{
				pEnum->Release();
				*ppPin = pPin;
				return S_OK;
			}
		}
		pPin->Release();
	}
	pEnum->Release();
	// Did not find a matching pin.
	return E_FAIL;
}

HRESULT DxFuncs::CreateFilterGraph(IGraphBuilder **pGraph)
{
	HRESULT hr;

	if (!pGraph)
		return E_POINTER;

	hr = CoCreateInstance(CLSID_FilterGraph, // get the graph object
		NULL,
		CLSCTX_INPROC_SERVER,
		IID_IGraphBuilder,
		(void **) pGraph);

	if(FAILED(hr))
	{
		_tprintf(_T("CreateFilterGraph: Failed to create graph!  hr=0x%x\n"), hr);
		*pGraph = NULL;
		return hr;
	}

	return S_OK;
}

HRESULT DxFuncs::CreateFilter(REFCLSID clsid, IBaseFilter **ppFilter)
{
	if (!ppFilter)
		return E_POINTER;

	HRESULT hr = CoCreateInstance(clsid,
		NULL,
		CLSCTX_INPROC_SERVER,
		IID_IBaseFilter,
		(void **) ppFilter);

	if(FAILED(hr))
	{
		*ppFilter = NULL;
		return hr;
	}

	return S_OK;
}

